package com.catchu.ssm.shiro;

import java.util.ArrayList;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.catchu.ssm.po.ActiveUser;
import com.catchu.ssm.po.SysPermission;
import com.catchu.ssm.po.SysUser;
import com.catchu.ssm.service.SysService;

/**
 * @author 刘俊重
 * @Description 自定义Realm
 * @date 2017年8月1日
 */
public class CustomRealm extends AuthorizingRealm {
	
	@Autowired
	private SysService sysService;

	/**
	 * @Description 用于授权
	 * @Author 刘俊重
	 * @date 2017年8月1日
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		//从principals中获取主身份信息。在上一步认证中把身份信息activeUser放进了SimpleAuthenticationInfo，这里再取出来。
		ActiveUser activeUser = (ActiveUser) principals.getPrimaryPrincipal();
		
		//从数据库中根据身份信息查询到的权限信息
		List<SysPermission> permissionList = null;
		try {
			permissionList = sysService.findPermissionListByUserId(activeUser.getUserid());
		} catch (Exception e) {
			e.printStackTrace();
		}
		List<String> permissions = new ArrayList<String>();
		if(permissionList!=null && permissionList.size()>0){
			for(SysPermission permission:permissionList){
				//将用户权限标识符放在list之后填充到SimpleAuthorizationInfo并返回
				permissions.add(permission.getPercode());
			}
		}
		
		//构建授权信息，并返回
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		simpleAuthorizationInfo.addStringPermissions(permissions);
		return simpleAuthorizationInfo;
	}

	/**
	 * @Description 用于认证
	 * @Author 刘俊重
	 * @date 2017年8月1日
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		
		//从token获取principal（身份信息）,token中存的是用户名和密码
		String userCode = (String) token.getPrincipal();
		
		//根据用户名查询用户信息
		SysUser sysUser = null;
		try {
			sysUser = sysService.findSysUserByUserCode(userCode);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		//用户不存在返回null
		if(null== sysUser){
			return null;
		}
		
		//用户存在，获取用户密码，盐
		String password = sysUser.getPassword();
		String salt = sysUser.getSalt();
		
		//activeUser就是用户的身份信息
		ActiveUser activeUser = new ActiveUser();
		activeUser.setUserid("zhangsan");
		activeUser.setUsercode("zhangsan");
		activeUser.setUsername("zhangsan");
		//根据用户id查询菜单
		List<SysPermission> menuList = null;
		try {
			menuList = sysService.findMenuListByUserId("zhangsan");
		} catch (Exception e) {
			e.printStackTrace();
		}
		activeUser.setMenus(menuList);
		
		//将用户身份信息activeUser设置到SimpleAuthenticationInfo中
		SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(activeUser,
				password,ByteSource.Util.bytes(salt),getName());
		return simpleAuthenticationInfo;
	}

	//清除缓存
	public void clearCached() {
		PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
		super.clearCache(principals);
	}
	
}
